#!/usr/bin/env bash

################################################################################
# Run all the tests using randomized values for number of packets, fill
# character and packet length.
################################################################################

usage() {
    cat <<EOF
randomized_tests:
	-h		Show this help and exit
	-j ID		Run only the test specified by ID
	-l		List available tests and exit
	-v		Increase verbosity of the tests
	-L		Skip legacy API
EOF
}

functionals="functional functional-legacy"

# Option parsing
OUTPUT="/dev/null"
while getopts "hlvj:L" opt; do
	case $opt in
	"h")
		usage
		exit 0
		;;

	"j")
		if [ -n "$2" ]; then
			TESTID=${OPTARG}
		else
			echo "-j requires an ID argument"
			exit 1
		fi
		;;

	"l")
		LIST="y"
		;;

	"v")
		# Select verbosity:
		#    -v    -> prints error messages
		#    -vv   -> -v, send and receive actions
		#    -vvv  -> -vv and packet building
		#    -vvvv -> -vvv and arguments parsing
		if [ -z "$VERB" ]; then
			VERB="-"
		fi
		VERB="${VERB}v"
		OUTPUT="/dev/stdout"
		;;
	"L")
		functionals="functional"
		;;

	\?)
		echo "Unknown option '$opt'"
		echo ""
		usage
		exit 1
		;;
	esac
done

# Support for colored output
RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
ORANGE='\033[0;33m'
NOC='\033[0m' # No Color

if [ -n "$LIST" ]; then
	pushd $(pwd)
	cd $(dirname $0)
	echo "Available tests:"
	i="1"
	for t in tests/* ; do
		printf "    #%03d: %s\n" $i $t
		i=$((i + 1))
	done
	popd
	exit 0
fi

if [ "$EUID" -ne "0" ]; then
	echo "This script must be run as root"
	exit 1
fi

which vale-ctl
if [ "$?" != "0" ]; then
	echo "vale-ctl program not not found"
	exit 1
fi

which bc
if [ "$?" != "0" ]; then
	echo "bc program not not found"
	exit 1
fi

random_num="$((65 + $RANDOM % 58))"
# https://stackoverflow.com/a/10503163
random_fill=$(printf \\$(printf '%03o' $random_num))
# We need to make sure that we can send this number of packets with this length
# at once. At the moment i just put max values which works for the defaults
# number of rings and buffer size.
random_len="$((50 + $RANDOM % 10000))"
random_packet_num="$((1 + $RANDOM % 100))"
# Use and empty string instead of "-q" if you don't want to perform a sequential
# send/receive check
seq_check="-q"

echo "Running tests with"
echo "   number of packets: ${random_packet_num}"
echo "   fill character   : ${random_fill}"
echo "   sequence check   : ${seq_check}"
echo "   packet length    : ${random_len}"
echo ""

# Save current directory and enter the utils/ directory.
pushd $(pwd)
cd $(dirname $0)

# Add the current directory (and build-utils) to the PATH. In this way we can
# easily invoke functional, get_avail_tx_packets and the other executables
# from the test scripts.
PATH="$(pwd)/../build-utils:$(pwd):${PATH}"

source test_lib

netmap_load

RET=0
i=0
for f in $functionals; do
	export FUNCTIONAL=$f
	echo -e "${ORANGE}>>> Running tests using $FUNCTIONAL"
	for t in tests/* ; do
		i=$((i + 1))

		# Possibly filter tests by TESTID
		[ -n "$TESTID" ] && [ "$i" != "$TESTID" ] && continue

		# Run this test
		echo -e "${ORANGE}>>> Running test #${i}: ${CYAN}\"${t}\"${NOC}"
		restart_fd_server
		$t $VERB -n $random_packet_num -l $random_len -f $random_fill "$seq_check" 2>${OUTPUT}
		res="$?"
		close_fd_server
		if [ "$res" == 0 ]; then
			echo -e "${GREEN}>>> Test #${i} PASSED${NOC}"
		else
			echo -e "${RED}>>> Test #${i} FAILED${NOC}"
			RET="1"
			break
		fi
	done
	[ "$RET" == 0 ] || break
done

# Wait for the fd_server to terminate and release its references
sleep 0.5

netmap_unload

popd
exit ${RET}
